package ejb.updater;

import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

public class XMLParserV2 {
	private XPathFactory xpf;
	private DocumentBuilderFactory fact; 
	private Document doc;
	
	public XMLParserV2(InputStream is) {
		xpf = XPathFactory.newInstance();
		fact = DocumentBuilderFactory.newInstance();
		fact.setNamespaceAware(true);
		try {
			doc = fact.newDocumentBuilder().parse(is);
			System.out.println("XML opened.");
		} catch (SAXException e) {
			System.err.println("SAXException while parsing XML.");
		} catch (IOException e) {
			System.err.println("IOException while parsing XML.");
		} catch (ParserConfigurationException e) {
			System.err.println("ParserConfigurationException while parsing XML.");
		}
	}
	
	public int getCurrentTemp() {
		int temp = 0;
		XPath path = xpf.newXPath();
		try {
			XPathExpression ex = path.compile("/response/current_observation/temp_c");
			temp = new Double((Double) ex.evaluate(doc, XPathConstants.NUMBER)).intValue();
		} catch (XPathExpressionException e) {
			System.err.println("XPathExpressionException");
		}
		return temp;
	}
	
	public int getCurrentConditions() {
		XPath path = xpf.newXPath();
		try {
			XPathExpression ex = path.compile("/response/current_observation/weather");
			return convCondStrToInt((String) ex.evaluate(doc, XPathConstants.STRING));
		} catch(XPathExpressionException e) {
			System.err.println("XPathExpressionException");
		}
		return 0;
	}
	
	public double getCurrentPressure() {
		double press = 0.0f;
		XPath path = xpf.newXPath();
		try {
			XPathExpression ex = path.compile("/response/current_observation/pressure_mb");
			press = (Double) ex.evaluate(doc, XPathConstants.NUMBER);
		} catch (XPathExpressionException e) {
			System.err.println("XPathExpressionException");
		}
		return press;
	}
	
	public int[] getForecastTemperature(int plusday) {
		int temp[] = {0,0};
		XPath path = xpf.newXPath();
		try {
			XPathExpression ex1 = path.compile("/response/forecast/simpleforecast/forecastdays/forecastday["+plusday+"]/low/celsius");
			XPathExpression ex2 = path.compile("/response/forecast/simpleforecast/forecastdays/forecastday["+plusday+"]/high/celsius");
			temp[0] = new Double((Double) ex1.evaluate(doc, XPathConstants.NUMBER)).intValue();
			temp[1] = new Double((Double) ex2.evaluate(doc, XPathConstants.NUMBER)).intValue();
		} catch (XPathExpressionException e) {
			System.err.println("XPathExpressionException");
		}
		return temp;
	}

	public int getForecastConditions(int plusday) {
		XPath path = xpf.newXPath();
		try {
			XPathExpression ex1 = path.compile("/response/forecast/simpleforecast/forecastdays/forecastday["+plusday+"]/conditions");
			return convCondStrToInt((String) ex1.evaluate(doc, XPathConstants.STRING));
			
		} catch (XPathExpressionException e) {
			System.err.println("XPathExpressionException");
		}
		return 0;
	}
	
	private static int convCondStrToInt(String str) {
		if(str.equals("Clear"))
			return 0;
		if(str.equals("Partly Cloudy"))
			return 1;
		if(str.equals("Mostly Cloudy") ||
				str.equals("Overcast") ||
				str.equals("Light Mist") ||
				str.equals("Mist") ||
				str.equals("Heavy Mist") ||
				str.equals("Light Fog") ||
				str.equals("Fog") ||
				str.equals("Heavy Fog"))
			return 2;
		if(str.equals("Light Rain") ||
				str.equals("Rain") ||
				str.equals("Heavy Rain") ||
				str.equals("Light Rain Mist") ||
				str.equals("Rain Mist") ||
				str.equals("Heavy Rain Mist") ||
				str.equals("Light Rain Showers") ||
				str.equals("Rain Showers") ||
				str.equals("Heavy Rain Showers"))
			return 3;
		if(str.equals("Light Thunderstorm") ||
				str.equals("Thunderstorm") ||
				str.equals("Heavy Thunderstorm") ||
				str.equals("Light Thunderstorms and Rain") ||
				str.equals("Thunderstorms and Rain") ||
				str.equals("Heavy Thunderstorms and Rain"))
			return 4;
		if(str.equals("Light Snow") ||
				str.equals("Snow") ||
				str.equals("Heavy Snow") ||
				str.equals("Light Snow Grains") ||
				str.equals("Snow Grains") ||
				str.equals("Heavy Snow Grains")) 
			return 5;
		return 0;
	}
}
